package com.huiyou.adminapi.service;

import com.alibaba.fastjson.JSONObject;
import com.huiyou.adminapi.common.Request;
import com.huiyou.adminapi.common.model.AreaInfo;
import com.huiyou.adminapi.common.model.PseudoCode;
import com.huiyou.adminapi.common.utils.Base64Util;
import com.huiyou.adminapi.repository.AreaInfoRepository;
import com.huiyou.adminapi.repository.PseudoCodeRepository;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

import java.util.concurrent.atomic.AtomicInteger;

@Service
@Transactional(rollbackFor = Exception.class)
public class PseudoService {

    private PseudoCodeRepository pseudoCodeRepository;
    private AreaInfoRepository areaInfoRepository;

    @Autowired
    public PseudoService(PseudoCodeRepository pseudoCodeRepository, AreaInfoRepository areaInfoRepository) {
        this.pseudoCodeRepository = pseudoCodeRepository;
        this.areaInfoRepository = areaInfoRepository;
    }

    public Page<PseudoCode> findAll(String goodsName, String goodBatch, Pageable pageable) {

        return this.pseudoCodeRepository
            .findByGoodsNameContainingAndGoodsBatchContainingOrderByCreateTimeDesc(goodsName, goodBatch, pageable);
    }

    public PseudoCode findBySecurityId(String securityId, String ipAddress) {
        String ipJoinSecurityId = Base64Util.base64(securityId + ipAddress);

        PseudoCode pseudoCode =
            this.pseudoCodeRepository.findBySecurityCodeNumber(securityId).orElse(null);

        List<AreaInfo> areaInfos = areaInfoRepository.findAllByIpJoinSecurity(ipJoinSecurityId, new PageRequest(0, 10));

        if (pseudoCode != null && areaInfos.size() <= 0) {
            pseudoCode.setQueryNumber(pseudoCode.getQueryNumber() + 1);
            JSONObject json = Request.getAddress(ipAddress);
            AreaInfo areaInfo = new AreaInfo();
            areaInfo.setIpJoinSecurity(ipJoinSecurityId);
            areaInfo.setIpAddress(ipAddress);
            areaInfo.setPseudo(pseudoCode);

            if (json != null) {
                areaInfo.setCity(json.getString("city"));
                areaInfo.setCounty(json.getString("county"));
            }
            areaInfoRepository.save(areaInfo);
            pseudoCodeRepository.save(pseudoCode);
        }
        return pseudoCode;
    }


    public void save(List<String> qrCodes, PseudoCode pseudoCode) {

        List<PseudoCode> pseudoCodes =
            this.bindGoods(qrCodes, pseudoCode.getGoodsName(), pseudoCode.getGoodsBatch());

        pseudoCodeRepository.saveAll(pseudoCodes);
    }

    /**
     * 对商品进行二维码绑定
     */
    private List<PseudoCode> bindGoods(List<String> codes, String goodsName, String goodsBatch) {

        List<PseudoCode> pseudoCodes = new ArrayList<>();
        Page<PseudoCode> pseudo =
            pseudoCodeRepository.findByGoodsNameContainingAndGoodsBatchContainingOrderByGoodsNumber(goodsName, goodsBatch, new PageRequest(0, 10));

        List<PseudoCode> pseudoCodes1 = pseudo.getContent();
        AtomicInteger i = new AtomicInteger();
        codes.stream().distinct().forEach(code -> {
            PseudoCode pseudoCode = new PseudoCode();
            pseudoCode.setId(Base64Util.base64(code));
            pseudoCode.setGoodsName(goodsName);

            if (pseudoCodes1.size() > 0) {
                String number = pseudoCodes1.get(0).getGoodsBatch();
                pseudoCode.setGoodsNumber(String.valueOf(Integer.valueOf(number + 1)));
            } else {
                i.getAndIncrement();
                pseudoCode.setGoodsNumber(String.valueOf(number(goodsBatch) + i.get()));
            }

            pseudoCode.setGoodsBatch(goodsBatch);
            pseudoCode.setSecurityCodeNumber(code.trim());
            pseudoCode.setQueryNumber(0);
            pseudoCode.setCreateTime(System.currentTimeMillis());

            pseudoCodes.add(pseudoCode);
        });
        return pseudoCodes;
    }

    public void deleteByGoodsNameAndGoodsBatch(String goodsName, String goodsBatch) {
        pseudoCodeRepository.deleteByGoodsNameAndGoodsBatch(goodsName, goodsBatch);
    }

    public List<PseudoCode> findByGoodsBatchAndGoodsName(String batch, String name, Pageable pageable){
        return pseudoCodeRepository.findByGoodsBatchAndGoodsName(batch, name, pageable).getContent();
    }

    public void deleteById(String id){
        pseudoCodeRepository.deleteById(id);
    }

    private Long number(String goodsBatch) {
        return Long.parseLong(goodsBatch + "0000");
    }

}
